<script setup>
import { ref, reactive, computed, watch, nextTick, onMounted } from "vue";
import { ElLoading, ElMessage, ElMessageBox } from "element-plus";
import { useProcessStoreHook } from "../../store/modules/process";
import { useDetectionStoreHook } from "../../store/modules/detection";
import { useInfoStoreHook } from "../../store/modules/info";
import { useTableDragger } from "../../utils/dragger";
import { getShiftTime } from "../../utils/datetime";

const dataTableBoxRef = ref(null);
const dataTableInnerRef = ref(null);

const processStore = useProcessStoreHook();
const detection = useDetectionStoreHook();
const info = useInfoStoreHook();

const technicParams = computed(() => {
  const res = {};
  for (const key in processStore.technicParams) {
    if (Object.hasOwnProperty.call(processStore.technicParams, key)) {
      const item = processStore.technicParams[key];
      let label = "";
      if (item.min <= 0) label = "\n≤" + item.max;
      else if (item.max >= 999) label = "\n≥" + item.min;
      else label = `\n${item.min}~\n${item.max}`;
      if (item.symbol) label = item.symbol + label;
      res[key] = { label, ...item };
    }
  }
  return res;
});

const columnMap = computed(() => {
  const res = {};
  detection.fields.forEach((f) => (res[f.name] = f));
  return res;
});

const columns = computed(() => {
  return detection.fieldItems;
});

const timeColumns = ref([]);

const timeColumnsTimer = () => {
  const timeRange = getShiftTime();
  // 获取当前的时间列
  const result = [];
  while (timeRange[0] < timeRange[1]) {
    timeRange[0].setHours(timeRange[0].getHours() + 1);
    result.push(
      `${timeRange[0].getHours().toString().padStart(2, "0")}:${timeRange[0].getMinutes()}`
    );
  }
  timeColumns.value = result;
  setTimeout(() => {
    timeColumnsTimer();
  }, 10 * 1000);
};

onMounted(() => {
  timeColumnsTimer();
});

// table操作时间列由Date对象转换为字符串的钩子
const datetime2string = (row, column, cellValue) => {
  if (!row.uuid) {
    return row.create_at;
  }
  if (cellValue) {
    const datetime = new Date(cellValue);
    return (
      // `${(datetime.getMonth() + 1).toString().padStart(2, '0')}月` +
      // `${datetime.getDate().toString().padStart(2, '0')}日 ` +
      `${datetime.getHours().toString().padStart(2, "0")}:` +
      `${datetime.getMinutes().toString().padStart(2, "0")}`
    );
  }
};

// 身份信息由数字转换为文字
const identityArray = ["操作员", "班组长", "巡检员"];
const identity2string = (row, column, cellValue) => identityArray[cellValue];
// 是否上报转换为文字提示
const reported2string = (row, column, cellValue) => (cellValue ? "已提报" : "提报中");
// 目检项布尔值转换钩子，false转换为NG，true转换为OK
const checkResult2string = (row, column, cellValue) => {
  if (cellValue === undefined) return;
  if (columnMap.value[column.property].method === 1) {
    return cellValue ? "OK" : "NG";
  } else {
    return cellValue;
  }
};
// 数据是否合格的判定钩子
const renderCeilStyle = ({ row, column }) => {
  if (column.property === "reported") {
    if (row.reported) {
      return { color: "var(--el-color-primary)" };
    } else {
      return { color: "var(--el-color-warning)" };
    }
  }
  const param = technicParams.value[column.property];
  if (!param) return;
  const data = row[column.property];
  if (data < param.min || data > param.max) {
    return { color: "#ff4949" };
  }
  return;
};

const identityOptions = ["全部", "操作员", "班组长", "巡检员"]; // 人员类型分类 0 操作员，1 班组长，2 巡检员
const identityFilter = ref(-1); // 当前筛选的人员类型

// const tableData = computed(() => {
//   const result = [];
//   detection.dataset.forEach((ds) => {
//     if (ds.process != processStore.processSrc) return;
//     if (identityFilter.value !== -1 && identityFilter.value !== ds.identity) return;
//     const item = { ...ds };
//     const data = [...item.data];
//     delete item.data;
//     data.forEach((d) => (item[d.type] = d.value));
//     if (!item.finish) {
//       result.push(item);
//     }
//   });
//   return result;
// });
const tableData = computed(() => {
  const cache = {};
  let index = 1;
  const workTypeMap = {};
  info.workTypeOptions.forEach((wt) => (workTypeMap[wt.value] = wt.label));
  detection.dataset.forEach((ds) => {
    if (ds.process != processStore.processSrc) return;
    if (identityFilter.value !== -1 && identityFilter.value !== ds.identity) return;
    const item = { ...ds, id: ds.uuid };
    const data = [...item.data];
    delete item.data;
    data.forEach((d) => (item[d.type] = d.value));
    if (!cache[`${item.model}:${item.finish_at}`]) {
      let label = materialMap.value[item.model]
        ? materialMap.value[item.model] + `（${item.model}）`
        : item.model;
      if (item.finish_at) {
        const date = new Date(item.finish_at);
        const hour = date.getHours() > 9 ? date.getHours() : "0" + date.getHours();
        const minute = date.getMinutes() > 9 ? date.getMinutes() : "0" + date.getMinutes();
        label = `<${hour}:${minute}完成 ${workTypeMap[item.work_type]}> ` + label;
      } else {
        label = `<当前执行 ${workTypeMap[item.work_type]}> ` + label;
      }
      cache[`${item.model}:${item.finish_at}`] = {
        id: index++,
        children: [item],
        create_at: label
      };
    } else {
      cache[`${item.model}:${item.finish_at}`].children.push(item);
    }
  });
  const result = [];
  for (const key in cache) {
    const item = cache[key];
    if (item.children.length !== undefined) {
      item.create_at = item.create_at + ` 点检：${item.children.length} 次`;
    }
    item.children.sort((a, b) => b.create_at - a.create_at);
    result.push(item);
  }
  result.sort((a, b) => {
    return (
      b.children[b.children.length - 1].create_at - a.children[a.children.length - 1].create_at
    );
  });
  return result;
});

// 首项合并
const tableSpanMethod = ({ row, columnIndex }) => {
  if (!row.uuid) {
    if (columnIndex === 0) {
      return [1, 5 + columns.value.length];
    } else {
      return [0, 0];
    }
  }
};

// 获取物料代码及其名称
const materials = computed(() => Array.from(new Set(detection.dataset.map((v) => v.model))));
const materialMap = ref({});
// 默认展开行
const expandRowKeys = ref([]);

watch(tableData, async (val) => {
  if (val.length > 0) {
    expandRowKeys.value = [val[0].id + ""];
  }
});

watch(materials, async (val, oldVal) => {
  if (!val || val.length === 0) return;
  if (val + "" === oldVal + "") return;
  const res = await window.api.getPartModelMap(val);
  if (res.code === 200) {
    res.data.forEach((item) => (materialMap.value[item.material_code] = item.part_type));
  }
});

function onExpandChange(row, expanded) {
  const expands = [...expandRowKeys.value];
  if (row) {
    if (expanded) {
      expands.push(row.id + "");
    } else {
      const index = expands.indexOf(row.id);
      expands.splice(index, 1);
    }
  }
  expandRowKeys.value = expands;
}

// 当行点击时展开或关闭该行
function tableRowClick(row) {
  dataTableInnerRef.value.toggleRowExpansion(row);
}

const dataTableHeight = ref(0);
onMounted(() => {
  // 清空上次遗留的批次，重新开始
  window.api.finishBatch();
  const content = document.querySelector(".el-tabs__content");
  dataTableHeight.value = content.clientHeight - 16;
});
window.addEventListener("resize", () => {
  const content = document.querySelector(".el-tabs__content");
  dataTableHeight.value = content?.clientHeight - 16;
});

watch(tableData, (val) => {
  nextTick(() => dataTableInnerRef.value.scrollBarRef.setScrollTop((val.length + 1) * 40));
});

async function delData(uuid) {
  ElMessageBox.alert(`确认删除零件${uuid}的数据吗？`, "警告", {
    confirmButtonText: "确认",
    cancelButtonText: "取消",
    type: "warning"
  })
    .then(async () => {
      const loading = ElLoading.service();
      try {
        const res = await window.api.delRemoteData(uuid);
        if (res.code !== 0) {
          ElMessage.error("删除失败，请稍后重试！");
          return;
        }
        await window.api.delLocalData(uuid);
        await detection.updateDataset();
        ElMessage.success("删除成功！");
      } finally {
        loading.close();
      }
    })
    .catch(() => {});
}

const dataTableDragger = useTableDragger(dataTableInnerRef);

const dialogVisible = ref(false);
const dialogContentHeight = reactive({
  height: "100%",
  width: "100%",
  padding: "10vh 0"
});
onMounted(async () => {
  dialogContentHeight.height = window.innerHeight - 60 - 48 + "px";
  window.addEventListener("resize", () => {
    dialogContentHeight.height = window.innerHeight - 60 - 48 + "px";
  });
});

function dataTableHeaderClick(column) {
  if (column["property"] === "identity") {
    dialogVisible.value = true;
  }
}

function selectIdentity(identity) {
  identityFilter.value = identity;
  dialogVisible.value = false;
}
</script>

<template>
  <div ref="dataTableBoxRef" class="data-table">
    <el-table
      ref="dataTableInnerRef"
      style="user-select: none"
      fit
      border
      row-key="id"
      :data="tableData"
      :height="dataTableHeight"
      :cell-style="renderCeilStyle"
      :span-method="tableSpanMethod"
      :expand-row-keys="expandRowKeys"
      @expand-change="onExpandChange"
      @header-click="dataTableHeaderClick"
      @row-click="tableRowClick"
      @mousedown="dataTableDragger.mouseDownHandler"
      @mouseup="dataTableDragger.mouseUpHandler"
      @mousemove="dataTableDragger.mouseMoveHandler"
      @mouseleave="dataTableDragger.mouseUpHandler"
    >
      <!-- <el-table-column
        align="right"
        label="序号"
        fixed="left"
        type="index"
        width="42px"
        :resizable="false"
      /> -->
      <el-table-column
        prop="create_at"
        label="时间"
        :formatter="datetime2string"
        width="62px"
        :resizable="false"
      />
      <el-table-column
        prop="identity"
        align="center"
        :label="`身份\n(${identityOptions[identityFilter + 1]})`"
        header-align="center"
        :formatter="identity2string"
        width="76px"
        :resizable="false"
      />
      <el-table-column
        v-for="item in columns"
        :key="item.text"
        header-align="center"
        :prop="item.text"
        :label="item.text + (technicParams[item.text] ? `${technicParams[item.text].label}` : '')"
        :formatter="checkResult2string"
        :min-width="item.method === 1 ? '46px' : '94px'"
        :resizable="false"
      />
      <el-table-column
        prop="operator_name"
        align="center"
        label="操作人"
        width="96px"
        :resizable="false"
      />
      <el-table-column
        prop="reported"
        label="状态"
        align="center"
        :formatter="reported2string"
        width="88px"
        :resizable="false"
      />
      <!-- 没有扫码过程，暂时取消不显示 -->
      <!-- <el-table-column prop="uuid" label="编码" width="300px" :resizable="false" /> -->
      <el-table-column
        v-if="info.identity"
        fixed="right"
        align="center"
        prop="options"
        label="操作"
        width="64px"
        :resizable="false"
      >
        <template #default="{ row }">
          <el-button type="danger" size="small" class="del-btn" @click="delData(row.uuid)"
            >删 除</el-button
          >
        </template>
      </el-table-column>
    </el-table>
  </div>
  <el-dialog v-model="dialogVisible" fullscreen>
    <el-row :gutter="12" :style="dialogContentHeight">
      <el-col v-for="(item, index) in identityOptions" :key="index" :span="12">
        <el-button
          :type="index - 1 === identityFilter ? 'primary' : ''"
          class="selection"
          @click="selectIdentity(index - 1)"
          >{{ item }}</el-button
        >
      </el-col>
    </el-row>
  </el-dialog>
</template>

<style lang="scss" scoped>
.data-table {
  height: calc(100% - 16px);
  margin: 0 12px 0 12px;
}
:deep(.header-box) {
  display: flex;
  height: 24px;
  line-height: 24px;
  justify-content: center;
  align-items: center;
  cursor: pointer;
  .el-icon {
    margin-right: 4px;
  }
}
:deep(.el-button) {
  height: 28px !important;
  width: 50px !important;
  font-size: 14px !important;
}
.selection {
  height: 90% !important;
  width: 100% !important;
  font-size: 22px !important;
  margin: 12px !important;
}
:deep(.el-table th > .cell) {
  white-space: pre-wrap;
}
:deep(.el-table__indent) {
  padding: 0 !important;
}
:deep(.el-table__placeholder) {
  padding: 0 !important;
  width: 0 !important;
}
</style>
